package tool

import java.io.File
import java.nio.file.Files
import com.typesafe.config.Config
import dao.ModeDao

import javax.inject.Inject
import org.apache.commons.lang3.StringUtils
import org.joda.time.DateTime
import play.api.mvc.RequestHeader
import utils.{DesEncrypter, Utils}

import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
import models.Tables._
import play.api.libs.json.Json

import scala.math.BigDecimal.RoundingMode
import tool.Pojo.{OrignalData, PredictData}
import utils.Implicits._
import implicits.Implicits._
import shared.Shared

import java.net.URLEncoder

/**
 * Created by yz on 2018/8/23
 */
class Tool @Inject()(modeDao: ModeDao, config: Config) {

  val rScript = {
    val rPath = config.getString("my.rPath")
    if (rPath == "Rscript") {
      "Rscript"
    } else {
      s"${rPath}/Rscript"
    }

  }

  val baseDir = {
    config.getString("my.baseDir")
  }

  val rPath = new File(baseDir, "bin/rScripts")
  val binDir = new File(baseDir, "bin")
  val workspaceDir = new File(baseDir, "workspace")

  val dataDir = if (Utils.dataDir.exists()) {
    Utils.dataDir
  } else {
    new File(baseDir, s"${Utils.dbName}/data")
  }

  val path = if (Utils.dataDir.exists()) {
    new File(Utils.path)
  } else {
    new File(baseDir, s"${Utils.dbName}")
  }

  def getUserName(implicit request: RequestHeader) = {
    request.session.get(Shared.userStr).get
  }

  def getTimes(times: Option[Int]) = times.map(_.toString).getOrElse("不限")

  def dataTime2String(dateTime: Option[DateTime]) = dateTime.map(_.toString("yyyy-MM-dd HH:mm:ss")).getOrElse("不限")

  val newPasswordDesEncrypter = new DesEncrypter("newPassword12345")

  val registerDesEncrypter = new DesEncrypter("register12345678")

  def createTempDirectory(prefix: String) = {
    if (isTestMode) {
      new File(workspaceDir, "myWorkspace")
    } else {
      Files.createTempDirectory(workspaceDir.toPath, "tmpDir").toFile
    }
  }

  def isTestMode = {
    val mode = Utils.execFuture(modeDao.select)
    if (mode.test == "t") true else false
  }

  def deleteDirectory(direcotry: File) = {
    if (!isTestMode) Utils.deleteDirectory(direcotry)
  }

  def getPredictValue(file: File): Map[String, String] = {
    val lines = file.lines
    getPredictValue(lines)
  }

  def getPredictValue(lines: List[String]): Map[String, String] = {
    val headers = lines.head.split("\t")
    headers.zip(lines(1).split("\t")).toMap
  }

  def getMissionIdDirById(missionId: Int)(implicit request: RequestHeader) = {
    val userMissionFile = getUserMissionDir
    new File(userMissionFile, missionId.toString)
  }

  def getUserMissionDir(implicit request: RequestHeader) = {
    new File(Utils.userDir, "mission")
  }

  def getUserIdDir(userId: Int) = {
    new File(Utils.userDir, userId.toString)
  }

  def getMissionJson(row: MissionRow) = {
    val missionMap = Utils.getMapByT(row)
    Json.toJson(missionMap)
  }

  case class MyMessage(valid: Boolean, message: String)

  def getOrinalData(lines: List[String]) = {
    val map = getPredictValue(lines)
    OrignalData(map("SampleID"), map("age"), map("bmi"), map("FBG"),
      map("GGT"), map("HDLch"), map("TBil"), map("albumin"), map("AST"), map("PLT"))
  }

  def getOrinalData(map: Map[String, String]) = {
    OrignalData(map.applyIgnoreCase("SampleID"), map.applyIgnoreCase("age"),
      map.applyIgnoreCase("bmi"), map.applyIgnoreCase("FBG"),
      map.applyIgnoreCase("GGT"), map.applyIgnoreCase("HDLch"), map.applyIgnoreCase("TBil"),
      map.applyIgnoreCase("ALB"), map.applyIgnoreCase("AST"), map.applyIgnoreCase("PLT"))
  }

  def getExtraData(file: File) = {
    val map = getPredictValue(file)
    ExtraDataF(getValue(map, "送检单位"), getValue(map, "地址"), getValue(map, "姓名"), getValue(map, "性别"),
      getValue(map, "送检科室"), getValue(map, "申请医生"), getValue(map, "门诊/住院号"), getValue(map, "采样时间"),
      getValue(map, "送检时间"), getValue(map, "样本类型"), getValue(map, "样本状态"),
      getValue(map, "标题"), getValue(map, "检验人"), getValue(map, "审核人"), getValue(map, "检验日期"),
      getValue(map, "报告日期")
    )
  }

  def getExtraData(map: Map[String,String]) = {
    ExtraDataF(getValue(map, "送检单位"), getValue(map, "地址"), getValue(map, "姓名"), getValue(map, "性别"),
      getValue(map, "送检科室"), getValue(map, "申请医生"), getValue(map, "门诊/住院号"), getValue(map, "采样时间"),
      getValue(map, "送检时间"), getValue(map, "样本类型"), getValue(map, "样本状态"),
      getValue(map, "标题"), getValue(map, "检验人"), getValue(map, "审核人"), getValue(map, "检验日期"),
      getValue(map, "报告日期")
    )
  }

  def getValue(map: Map[String, String], header: String) = {
    val str = map.getOrElse(header, "NA")
    if (str == "NA") "" else str
  }

  def getEmptyExtraDataRow(id: Int, userId: Int) = {
    ExtraDataRow(id, userId, "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "")
  }

}

object Tool {

  def getUserId(implicit request: RequestHeader) = {
    request.session.get(Utils.idStr).get.toInt
  }

  def dataCheck(data:PredictData)={
    PredictDataValidTool.valid(data)
  }

  def getContentDisposition(url: String) = {
    val encodeUrl = Tool.urlEncode(url)
    s"attachment; filename*=utf-8''${encodeUrl}"
  }

  def urlEncode(url: String) = {
    URLEncoder.encode(url, "UTF-8")
  }


}
